package com.huawei.hwclouds.vpc.demo;

import com.huaweicloud.sdk.core.auth.BasicCredentials;
import com.huaweicloud.sdk.core.auth.ICredential;
import com.huaweicloud.sdk.core.exception.ConnectionException;
import com.huaweicloud.sdk.core.exception.RequestTimeoutException;
import com.huaweicloud.sdk.core.exception.ServiceResponseException;
import com.huaweicloud.sdk.core.http.HttpConfig;
import com.huaweicloud.sdk.vpc.v2.model.ListPortsRequest;
import com.huaweicloud.sdk.vpc.v2.model.ListPortsResponse;
import com.huaweicloud.sdk.vpc.v3.model.CreateSubNetworkInterfaceOption;
import com.huaweicloud.sdk.vpc.v3.model.CreateSubNetworkInterfaceRequest;
import com.huaweicloud.sdk.vpc.v3.model.CreateSubNetworkInterfaceRequestBody;
import com.huaweicloud.sdk.vpc.v3.model.CreateSubNetworkInterfaceResponse;
import com.huaweicloud.sdk.vpc.v3.model.DeleteSubNetworkInterfaceRequest;
import com.huaweicloud.sdk.vpc.v3.model.DeleteSubNetworkInterfaceResponse;
import com.huaweicloud.sdk.vpc.v3.model.ListSecurityGroupsRequest;
import com.huaweicloud.sdk.vpc.v3.model.ListSecurityGroupsResponse;
import com.huaweicloud.sdk.vpc.v3.model.UpdateSubNetworkInterfaceOption;
import com.huaweicloud.sdk.vpc.v3.model.UpdateSubNetworkInterfaceRequest;
import com.huaweicloud.sdk.vpc.v3.model.UpdateSubNetworkInterfaceRequestBody;
import com.huaweicloud.sdk.vpc.v3.model.UpdateSubNetworkInterfaceResponse;
import com.huaweicloud.sdk.vpc.v3.region.VpcRegion;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Arrays;
import java.util.Objects;

/**
 * 配置云服务器的辅助弹性网卡
 */
public class VPCSubNetworkInterfaceDemo {
    private static final Logger logger = LoggerFactory.getLogger(VPCSubNetworkInterfaceDemo.class.getName());

    public static void main(String[] args) {
        // 输入华为云账号的AK、SK
        String ak = "{YOUR AK}";
        String sk = "{YOUR SK}";

        // 支持辅助弹性网卡的云服务器id
        String ecsId = "{ecs_id}";

        ICredential auth = new BasicCredentials()
            .withAk(ak)
            .withSk(sk);

        // HTTP客户端配置
        HttpConfig httpConfig = HttpConfig.getDefaultHttpConfig().withIgnoreSSLVerification(true);

        // v2接口的VpcClient，region_id处填写应用区域的id，如北京四填写cn-north-4
        com.huaweicloud.sdk.vpc.v2.VpcClient clientV2 = com.huaweicloud.sdk.vpc.v2.VpcClient.newBuilder()
            .withCredential(auth)
            .withRegion(VpcRegion.valueOf("{region_id}"))
            .withHttpConfig(httpConfig)
            .build();

        // v3接口的VpcClient，region_id处填写应用区域的id，如北京四填写cn-north-4
        com.huaweicloud.sdk.vpc.v3.VpcClient clientV3 = com.huaweicloud.sdk.vpc.v3.VpcClient.newBuilder()
            .withCredential(auth)
            .withRegion(VpcRegion.valueOf("{region_id}"))
            .withHttpConfig(httpConfig)
            .build();

        VPCSubNetworkInterfaceDemo demo = new VPCSubNetworkInterfaceDemo();
        // 根据云服务器的ID查询网卡和网络信息
        ListPortsResponse listPortsResponse = demo.listPorts(clientV2, ecsId);
        if (Objects.isNull(listPortsResponse)) {
            logger.error("Failed to query the ENI of ECS {}.", ecsId);
            return;
        }
        String portId = listPortsResponse.getPorts().get(0).getId();
        String networkId = listPortsResponse.getPorts().get(0).getNetworkId();

        // 查询当前已有的安全组
        ListSecurityGroupsResponse listSecurityGroupsResponse = demo.listSecurityGroups(clientV3);
        if (listSecurityGroupsResponse.getSecurityGroups().isEmpty()) {
            logger.error("The current tenant does not have any security groups.");
            return;
        }
        String securityGroupId = listSecurityGroupsResponse.getSecurityGroups().get(0).getId();

        // 根据网卡、网络和安全组信息创建辅助弹性网卡
        CreateSubNetworkInterfaceResponse createSubEniResponse =
            demo.createSubNetworkInterface(clientV3, portId, networkId, securityGroupId);
        String subEniId = createSubEniResponse.getSubNetworkInterface().getId();
        // 更新辅助弹性网卡绑定的安全组
        demo.updateSubNetworkInterface(clientV3, subEniId,
            listSecurityGroupsResponse.getSecurityGroups().get(1).getId());
        // 删除辅助弹性网卡
        demo.deleteSubNetworkInterface(clientV3, subEniId);
    }

    private ListPortsResponse listPorts(com.huaweicloud.sdk.vpc.v2.VpcClient vpcClient, String ecsId) {
        ListPortsRequest listPortsRequest = new ListPortsRequest().withDeviceId(ecsId);
        ListPortsResponse listPortsResponse = null;
        try {
            listPortsResponse = vpcClient.listPorts(listPortsRequest);
            logger.info(listPortsResponse.toString());
        } catch (ConnectionException e) {
            logger.error(e.toString());
        } catch (RequestTimeoutException e) {
            logger.error(e.toString());
        } catch (ServiceResponseException e) {
            logger.error(e.toString());
        }
        return listPortsResponse;
    }

    private ListSecurityGroupsResponse listSecurityGroups(com.huaweicloud.sdk.vpc.v3.VpcClient vpcClient) {
        ListSecurityGroupsRequest listSecurityGroupsRequest = new ListSecurityGroupsRequest().withLimit(2);
        ListSecurityGroupsResponse listSecurityGroupsResponse = null;
        try {
            listSecurityGroupsResponse = vpcClient.listSecurityGroups(listSecurityGroupsRequest);
            logger.info(listSecurityGroupsResponse.toString());
        } catch (ConnectionException e) {
            logger.error(e.toString());
        } catch (RequestTimeoutException e) {
            logger.error(e.toString());
        } catch (ServiceResponseException e) {
            logger.error(e.toString());
        }
        return listSecurityGroupsResponse;
    }

    private CreateSubNetworkInterfaceResponse createSubNetworkInterface(com.huaweicloud.sdk.vpc.v3.VpcClient vpcClient,
        String parentPortId, String virSubnetId, String securityGroupId) {
        CreateSubNetworkInterfaceRequest createSubEniRequest = new CreateSubNetworkInterfaceRequest()
            .withBody(new CreateSubNetworkInterfaceRequestBody()
                .withSubNetworkInterface(new CreateSubNetworkInterfaceOption()
                    .withParentId(parentPortId)
                    .withVirsubnetId(virSubnetId)
                    .withSecurityGroups(Arrays.asList(securityGroupId))));
        CreateSubNetworkInterfaceResponse createSubEniResponse = null;
        try {
            createSubEniResponse = vpcClient.createSubNetworkInterface(createSubEniRequest);
            logger.info(createSubEniResponse.toString());
        } catch (ConnectionException e) {
            logger.error(e.toString());
        } catch (RequestTimeoutException e) {
            logger.error(e.toString());
        } catch (ServiceResponseException e) {
            logger.error(e.toString());
        }
        return createSubEniResponse;
    }

    private void updateSubNetworkInterface(com.huaweicloud.sdk.vpc.v3.VpcClient vpcClient,
        String subEniId, String securityGroupId) {
        UpdateSubNetworkInterfaceRequest updateSubEniRequest = new UpdateSubNetworkInterfaceRequest()
            .withSubNetworkInterfaceId(subEniId)
            .withBody(new UpdateSubNetworkInterfaceRequestBody()
                .withSubNetworkInterface(new UpdateSubNetworkInterfaceOption()
                    .withSecurityGroups(Arrays.asList(securityGroupId))));
        try {
            UpdateSubNetworkInterfaceResponse updateSubEniResponse =
                vpcClient.updateSubNetworkInterface(updateSubEniRequest);
            logger.info(updateSubEniResponse.toString());
        } catch (ConnectionException e) {
            logger.error(e.toString());
        } catch (RequestTimeoutException e) {
            logger.error(e.toString());
        } catch (ServiceResponseException e) {
            logger.error(e.toString());
        }
    }

    private void deleteSubNetworkInterface(com.huaweicloud.sdk.vpc.v3.VpcClient vpcClient, String subEniId) {
        DeleteSubNetworkInterfaceRequest deleteSubEniRequest = new DeleteSubNetworkInterfaceRequest()
            .withSubNetworkInterfaceId(subEniId);
        try {
            DeleteSubNetworkInterfaceResponse deleteSubEniResponse =
                vpcClient.deleteSubNetworkInterface(deleteSubEniRequest);
            logger.info(deleteSubEniResponse.toString());
        } catch (ConnectionException e) {
            logger.error(e.toString());
        } catch (RequestTimeoutException e) {
            logger.error(e.toString());
        } catch (ServiceResponseException e) {
            logger.error(e.toString());
        }
    }
}